package thread.test4Queue;

import org.junit.Test;
import thread.test4Queue.domain.Person;
import thread.test4Queue.domain.PersonDelay;

import java.util.concurrent.*;

/**
 * queue 接口下游blockingQueue,blokingDequeue,Dequeue
 *
 * blockingQueue 接口下都是线程安全的,
 * 如果不设置队列容量的话，是Integer.max
 * 阻塞队列不允许有null元素
 *
 * Created by majian8 on 2018/11/12.
 */
public class Test1BlockingQueue {
    /**
     * 1,ArrayBlockingQueue
     *
     *fifo 队列。通过设置公平策略来，保证顺序,可以设置队列大小，默认 Interger.value
     */
    @Test
    public void test1() throws InterruptedException {
        ArrayBlockingQueue queue=new ArrayBlockingQueue(200,true);
        queue.put(111);
        System.out.println("---->"+queue.size());
        Object a=queue.take();
        System.out.println(a);
        System.out.println("=====>"+queue.size());
    }



    /**
     * 2,LinkedBlockingQueue
     * fifo 有界队列，默认 Interger.max_value 几乎同arrayBlockingQueue ,只是内部锁实现不一样
     */
    @Test
    public void test2(){

    }

    /**
     * 3,LinkedBlockingDeque
     *
     * 无界双端队列，默认，Integer.MAX_VALUE，可以对首尾进行操作，线程安全，
     * blockingQueue接口下都是线程安全的
     */
    @Test
    public void test3(){

    }

    /**
     * 4,DelayQueue
     * 延迟队列,无界限队列
     *
     */
    @Test
    public void test4() throws InterruptedException {
        PersonDelay person1=new PersonDelay(10000,"zhangsan");
        PersonDelay person2=new PersonDelay(5000,"lisi");
        DelayQueue<PersonDelay> queue=new DelayQueue<>();
        queue.put(person1);
        queue.put(person2);
        System.out.println(queue.take().getName());
        System.out.println(queue.take().getName());
        System.out.println("====");
        System.out.println(queue.poll(2, TimeUnit.SECONDS).getName());

    }


    /**
     *
     * 5,PriorityBlockingQueue
     * 优先级队列,无界队列，排序队列（要实现比较器），线程安全的。
     */
    @Test
    public void test5() throws InterruptedException {
        PriorityBlockingQueue<Person> queue=new PriorityBlockingQueue<>();
        Person p1=new Person();
        p1.setName("zhangsan");
        p1.setAge(20);

        Person p2=new Person();
        p2.setName("lisi");
        p2.setAge(50);

        Person p3=new Person();
        p3.setName("wangwu");
        p3.setAge(30);

        queue.put(p1);
        queue.put(p2);
        queue.put(p3);

        System.out.println(queue.take().getName());
        System.out.println(queue.take().getName());
        System.out.println(queue.take().getName());
    }



    /**
     * SynchronousQueue
     *
     * 同步队列，
     * 其中每个插入操作必须等待另一个线程的对应移除操作 ，
     * 反之亦然。同步队列没有任何内部容量，甚至连一个队列的容量都没有
     * 提供的有公平策略
     *
     */
    @Test
    public void test6(){

        final SynchronousQueue queue=new SynchronousQueue();

        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1;i<=10;i++){
                    System.out.println("start put "+i);
                    try {
                        queue.put(i);
                        System.out.println("end put 0000  "+i);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1;i<=10;i++){
                    try {
                        System.out.println("开始取数据 "+queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        t1.start();
        t2.start();

        if(Thread.activeCount()>1){
            Thread.yield();
        }
    }


}
